package com.fingard.dsp.bank.directbank.cmbc02;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IRealTime;
import com.fingard.dsp.bank.directbank.pab02.Util.api.utils.StringUtil;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.text.StringHelper;

/**
 * 民生收付易单笔实时代扣
 * 
 * 参考文档：【直连测试】中国民生银行_收付易商户直连接口文档v1.1.5.2.xls
 * 
 * 开发接口：
 * 			1、单笔代收交易(PAY_T004)
 * 			2、单笔交易状态查询(PAY_Q001)
 * 
 * @author Cruise
 * @date 2019/3/12
 */
public class CMBC02RealTime extends CMBC02Base implements IRealTime {
	@SuppressWarnings("unchecked")
	@Override
	public RetAtsSingle d_9108_RealTimeRec(ReqSingle p_req9108) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9108.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9108.singleDetail.recAct, "");
			if (actItem == null) {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = "未找到账号[" + p_req9108.singleDetail.recAct + "]商户配置信息!";
				tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
				tmpRetDetail.transState = PaymentState.FAIL_Payment;
				tmpRetDetail.payInfoCode = FailCode.E9981;
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}
			// 组装请求报文
			String version = "v1.0";
			String source = "PC";
			String merchantNum = actItem.merchantId;
			String merchantSeq = p_req9108.singleDetail.askNumber;
			boolean padSingleSeq50 = getBankConfig().getValueAsBool("padSingleSeq50");
			this.WriteBankLogLn("padSingleSeq50:"+padSingleSeq50);
			if(padSingleSeq50){
				merchantSeq = actItem.merchantId+"_"+p_req9108.singleDetail.askNumber+"_";
				merchantSeq = StringHelper.padByByte(merchantSeq, this.getCharset(reqHeader.transType), 50, '0', 'R');
			}
			String transDate = Format.Date8Format.format(p_req9108.singleDetail.getPayDateTime());
			String transTime = Format.Time9Format.format(p_req9108.singleDetail.getPayDateTime());
			String transCode = "PAY_T004";
			String securityType = "SM203";
			String reserve1 = "";
			String reserve2 = "";
			String reserve3 = "";
			String reserve4 = "";
			String reserve5 = "";
			String reserveJson = "";
			// 组装业务报文
			String defaultTradeType = "30010001";
			String contractId = actItem.getBusCode("singleRec");
			String subject = "";
			String body = "";
			String currencyCode = "RMB";
			String amount = p_req9108.singleDetail.payAmount;
			String bizType = "6001";
            String isprivate = p_req9108.singleDetail.isPrivate;
			String draweeAccType = "";
			String cardType = p_req9108.singleDetail.cardType;
			if (StringHelper.hasAnyChar(cardType)) {
                draweeAccType= convertCardTypeMapping(cardType);//不上送，默认为借记卡
			}else {
                draweeAccType="1";
			}
			if(!StringHelper.hasAnyChar(draweeAccType)){//默认为借记卡
                draweeAccType="1";
			}
            String draweePartyId = p_req9108.singleDetail.cnapsCode;
            if(!StringHelper.hasAnyChar(draweePartyId)){
                draweePartyId = "305100000013";
            }
			String draweePartyName = p_req9108.singleDetail.cnapsName;
			String draweeAccNo = p_req9108.singleDetail.payAct;
			String draweeAccName = p_req9108.singleDetail.payName;
			String draweeCertType = convertCertTypeToBank(p_req9108.singleDetail.certType);
			String draweeCertNo = p_req9108.singleDetail.certNum;
			String protocolId = "";
			String draweeCardCvn2 = "";
			String draweeCardexpire = "";
			String draweeMobileTel = "";
			String draweeCheckCode = "";
			String notifyUrl = "";
			String reqReserved = "";
			String riskRateInfo = "";
			String userMac = "";
			String reserved = "";
			// 发送给银行的报文
			Map<String, String> messagetoBank = new HashMap<String, String>();
			messagetoBank.put("version", version);
			messagetoBank.put("source", source);
			messagetoBank.put("merchantNum", merchantNum);
			messagetoBank.put("merchantSeq", merchantSeq);
			messagetoBank.put("transDate", transDate);
			messagetoBank.put("transTime", transTime);
			messagetoBank.put("transCode", transCode);
			messagetoBank.put("securityType", securityType);
			messagetoBank.put("reserve1", reserve1);
			messagetoBank.put("reserve2", reserve2);
			messagetoBank.put("reserve3", reserve3);
			messagetoBank.put("reserve4", reserve4);
			messagetoBank.put("reserve5", reserve5);
			messagetoBank.put("reserveJson", reserveJson);
			messagetoBank.put("defaultTradeType", defaultTradeType);
			messagetoBank.put("contractId", contractId);
			messagetoBank.put("subject", subject);
			messagetoBank.put("body", body);
			messagetoBank.put("currencyCode", currencyCode);
			messagetoBank.put("amount", amount);
			messagetoBank.put("bizType", bizType);
			messagetoBank.put("draweeAccType", draweeAccType);
			messagetoBank.put("draweePartyId", draweePartyId);
			messagetoBank.put("draweePartyName", draweePartyName);
			messagetoBank.put("draweeAccNo", draweeAccNo);
			messagetoBank.put("draweeAccName", draweeAccName);
			messagetoBank.put("draweeCertType", draweeCertType);
			messagetoBank.put("draweeCertNo", draweeCertNo);
			messagetoBank.put("protocolId", protocolId);
			messagetoBank.put("draweeCardCvn2", draweeCardCvn2);
			messagetoBank.put("draweeCardexpire", draweeCardexpire);
			messagetoBank.put("draweeMobileTel", draweeMobileTel);
			messagetoBank.put("draweeCheckCode", draweeCheckCode);
			messagetoBank.put("notifyUrl", notifyUrl);
			messagetoBank.put("reqReserved", reqReserved);
			messagetoBank.put("riskRateInfo", riskRateInfo);
			messagetoBank.put("userMac", userMac);
			messagetoBank.put("reserved", reserved);
			Map<String, String> submitMap = new HashMap<String, String>();
			Map<String, String> busiMap = new HashMap<String, String>();
			splidReqMap(messagetoBank, submitMap, busiMap);
			submitMap.put("businessContext", encodeMsgToString(p_req9108.singleDetail.recAct, busiMap));
			String message = submitMap.toString();
			WriteBankLogLn("发送给银行的报文：" + message);
			String tmpUrl = bankFront.getUrl("Pay");
			String[] tmpStrRet = sendToBank(submitMap, tmpUrl);
			if (tmpStrRet[0].length() == 0) {
				WriteBankLogLn("银行返回的报文：" + tmpStrRet[1]);
				Map<String, String> reMap = (Map<String, String>) JSON.parse(tmpStrRet[1].toString());
				WriteBankLogLn("解析后银行返回的报文map形式：" + reMap);
				WriteBankLogLn("解析后银行返回的报文：" + reMap.toString());
				String gateReturnType = reMap.get("gateReturnType");
				String code = reMap.get("gateReturnCode");
				String respInfo = reMap.get("gateReturnMessage");
				if ("S".equals(gateReturnType)) {
					String returnMessage = reMap.get("businessContext");
					WriteBankLogLn("银行返回报文中的businessContext：" + returnMessage);
					String returnbody = decodeMsgToString(p_req9108.singleDetail.recAct, returnMessage);
					WriteBankLogLn("解密结果：" + returnbody);
					Map<String, String> str = (Map<String, String>) JSON.parse(returnbody.toString());
					String busiType = str.get("busiType");
					String busiCode = str.get("busiCode");
					String busiMsg = str.get("busiMsg");
					tmpRetDetail.respCode = "0";
					tmpRetDetail.respInfo = busiMsg;
					tmpRetDetail.payInfoCode = busiType+ "+" +busiCode;
					tmpRetDetail.transState = busiType+ "+" +busiCode;
				} else if ("E".equals(gateReturnType)) {
					tmpRetDetail.respCode = "0";
					tmpRetDetail.respInfo = respInfo;
					tmpRetDetail.payInfoCode = code;
					tmpRetDetail.transState = code;
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = respInfo;
				}
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}

		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	@SuppressWarnings("unchecked")
	@Override
	public RetAtsSingle d_9144_QryRealTimeRec(ReqQrySingle p_req9144) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9144.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		tmpRetDetail.reqSeqID = p_req9144.askNumber;

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9144.recAct, "");
			if (actItem == null) {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = "未找到账号[" + p_req9144.recAct + "]商户配置信息!";
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}
			// 组装请求报文
			String version = "v1.0";
			String source = "PC";
			String merchantNum = actItem.merchantId;
			String merchantSeq = genMerchantSeq(merchantNum);
			Date timeNow = new Date();
			String transDate = Format.Date8Format.format(timeNow);
			String transTime = Format.Time9Format.format(timeNow);
			String transCode = "PAY_Q001";
			String securityType = "SM203";
			String reserve1 = "";
			String reserve2 = "";
			String reserve3 = "";
			String reserve4 = "";
			String reserve5 = "";
			String reserveJson = "";
			// 组装业务报文
			String contractId = actItem.getBusCode("singleRec");
			String defaultTradeType = "30010001";
			
			String orgMerchantSeq = p_req9144.askNumber;
			if(this.getBankConfig().getValueAsBool("padSingleSeq50")){
				orgMerchantSeq = actItem.merchantId+"_"+p_req9144.askNumber+"_";
				orgMerchantSeq = StringHelper.padByByte(orgMerchantSeq, this.getCharset(reqHeader.transType), 50, '0', 'R');
			}
			String reserved = "";
			// 发送给银行的报文
			Map<String, String> messagetoBank = new HashMap<String, String>();
			messagetoBank.put("version", version);
			messagetoBank.put("source", source);
			messagetoBank.put("merchantNum", merchantNum);
			messagetoBank.put("merchantSeq", merchantSeq);
			messagetoBank.put("transDate", transDate);
			messagetoBank.put("transTime", transTime);
			messagetoBank.put("transCode", transCode);
			messagetoBank.put("securityType", securityType);
			messagetoBank.put("reserve1", reserve1);
			messagetoBank.put("reserve2", reserve2);
			messagetoBank.put("reserve3", reserve3);
			messagetoBank.put("reserve4", reserve4);
			messagetoBank.put("reserve5", reserve5);
			messagetoBank.put("reserveJson", reserveJson);
			messagetoBank.put("contractId", contractId);
			messagetoBank.put("defaultTradeType", defaultTradeType);
			messagetoBank.put("orgMerchantSeq", orgMerchantSeq);
			messagetoBank.put("reserved", reserved);
			Map<String, String> submitMap = new HashMap<String, String>();
			Map<String, String> busiMap = new HashMap<String, String>();
			splidReqMap(messagetoBank, submitMap, busiMap);
			submitMap.put("businessContext", encodeMsgToString(p_req9144.recAct, busiMap));
			String message = submitMap.toString();
			WriteBankLogLn("发送给银行的报文：" + message);
			String tmpUrl = bankFront.getUrl("Query");
			String[] tmpStrRet = sendToBank(submitMap, tmpUrl);
			if (tmpStrRet[0].length() == 0) {
				WriteBankLogLn("银行返回的报文：" + tmpStrRet[1]);
				Map<String, String> reMap = (Map<String, String>) JSON.parse(tmpStrRet[1].toString());
				WriteBankLogLn("解析后银行返回的报文map形式：" + reMap);
				WriteBankLogLn("解析后银行返回的报文：" + reMap.toString());
				String gateReturnType = reMap.get("gateReturnType");
				String respInfo = reMap.get("gateReturnMessage");
				if ("S".equals(gateReturnType)) {
					String returnMessage = reMap.get("businessContext");
					WriteBankLogLn("银行返回报文中的businessContext：" + returnMessage);
					String returnbody = decodeMsgToString(p_req9144.recAct, returnMessage);
					WriteBankLogLn("解密结果：" + returnbody);
					Map<String, String> str = (Map<String, String>) JSON.parse(returnbody.toString());
					String busiType = str.get("busiType");
					String busiCode = str.get("busiCode");
					String busiMsg = str.get("busiMsg");
					if ("S".equals(busiType)) {
						String returnorgMerchantSeq = str.get("orgMerchantSeq");
						String platSeq = str.get("platSeq");
						String amount = str.get("amount");
						String status = str.get("status");
						tmpRetDetail.respCode = "0";
						tmpRetDetail.transState = busiCode+ "+" + status;
						tmpRetDetail.outTransID = platSeq;
						tmpRetDetail.transAmt = amount;
						reserved = str.get("reserved");
						if(!StringUtil.isNull(reserved)&&reserved.length()>7&&reserved.indexOf("|")>8){
						    tmpRetDetail.respInfo = reserved.substring(reserved.indexOf("errMsg")+7,reserved.indexOf("|"));
						    tmpRetDetail.payInfoCode = tmpRetDetail.respInfo;
						}
						if(returnorgMerchantSeq.equals(orgMerchantSeq)){
						    tmpRetDetail.reqSeqID = p_req9144.askNumber;
						}else{
						    tmpRetDetail.respCode = "-1";
						    tmpRetDetail.respInfo = "响应流水号"+returnorgMerchantSeq+"与请求"+orgMerchantSeq+"不相符";
						}
					}  else	if ("E".equals(busiType) && busiMsg.contains("数据库查询无记录")&&canBeNotExist(p_req9144, tmpRetDetail, 10)) {
						tmpRetDetail.respCode = "0";
						tmpRetDetail.respInfo = "数据库查询无记录";
						tmpRetDetail.transState =busiCode+"+"+busiMsg;
						tmpRetDetail.payInfoCode =busiCode;
						tmpRetDetail.reqSeqID = p_req9144.askNumber;
					}
					else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = busiMsg;
					}
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = respInfo;
				}
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}
}
